import React from 'react';

import type { Emoji } from '@emoji-mart/data';

import { type EmojiCategoryList, EmojiCategory } from '../../lib';

export type EmojiPickerStateDispatch = {
  type: string;
  payload?: Partial<EmojiPickerStateProps>;
};

export type EmojiPickerStateProps = {
  hasFound: boolean;
  isOpen: boolean;
  isSearching: boolean;
  searchResult: Emoji[];
  searchValue: string;
  visibleCategories: MapEmojiCategoryList;
  emoji?: Emoji;
  focusedCategory?: EmojiCategoryList;
  frequentEmoji?: string;
};

export type MapEmojiCategoryList = Map<EmojiCategoryList, boolean>;

const initialState: EmojiPickerStateProps = {
  emoji: undefined,
  focusedCategory: undefined,
  frequentEmoji: undefined,
  hasFound: false,
  isOpen: false,
  isSearching: false,
  searchResult: [],
  searchValue: '',
  visibleCategories: new Map(),
};

export const useEmojiPickerState = (): [
  EmojiPickerStateProps,
  React.Dispatch<EmojiPickerStateDispatch>,
] => {
  const [cache, dispatch] = React.useReducer(
    (state: EmojiPickerStateProps, action: EmojiPickerStateDispatch) => {
      const { payload, type } = action;

      switch (type) {
        case 'CLEAR_SEARCH': {
          return {
            ...state,
            focusedCategory: EmojiCategory.Frequent,
            hasFound: false,
            isSearching: false,
            searchValue: '',
          };
        }
        case 'SET_CLOSE': {
          return {
            ...state,
            emoji: undefined,
            isOpen: false,
          };
        }
        case 'SET_EMOJI':
        case 'SET_FOCUSED_AND_VISIBLE_CATEGORIES':
        case 'SET_SEARCH': {
          return { ...state, ...payload };
        }
        case 'SET_FOCUSED_CATEGORY': {
          return {
            ...state,
            ...payload,
            hasFound: false,
            isSearching: false,
            searchValue: '',
          };
        }
        case 'SET_OPEN': {
          return {
            ...state,
            isOpen: true,
          };
        }
        case 'UPDATE_FREQUENT_EMOJIS': {
          return {
            ...state,
            ...payload,
            emoji: undefined,
          };
        }
        case 'UPDATE_SEARCH_RESULT': {
          return {
            ...state,
            ...payload,
            focusedCategory: undefined,
            isSearching: true,
          };
        }
        default: {
          throw new Error(`Unhandled action type: ${type}`);
        }
      }
    },
    initialState
  );

  return [cache, dispatch];
};
